package com.funsport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.funsport.common.enums.UserRole;
import com.funsport.common.enums.UserStatus;
import com.funsport.dto.request.AdminUserCreateRequest;
import com.funsport.dto.request.AdminUserUpdateRequest;
import com.funsport.dto.response.AdminUserResponse;
import com.funsport.entity.Role;
import com.funsport.entity.User;
import com.funsport.mapper.RoleMapper;
import com.funsport.mapper.UserMapper;
import com.funsport.mapper.UserRoleMapper;
import com.funsport.service.AdminUserService;
import com.funsport.service.RoleService;
import com.funsport.service.UserRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 后台管理用户服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminUserServiceImpl implements AdminUserService {
    
    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleMapper roleMapper;
    private final RoleService roleService;
    private final UserRoleService userRoleService;
    private final PasswordEncoder passwordEncoder;
    
    @Override
    public Page<AdminUserResponse> getAdminUsers(Integer page, Integer pageSize, String keyword, String status) {
        Page<User> userPage = new Page<>(page, pageSize);
        
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 只查询后台管理员用户（admin和venue_manager）
        queryWrapper.in(User::getRole, UserRole.ADMIN, UserRole.VENUE_MANAGER);
        
        // 关键词搜索
        if (StringUtils.hasText(keyword)) {
            queryWrapper.and(wrapper -> wrapper
                .like(User::getNickname, keyword)
                .or()
                .like(User::getPhone, keyword)
                .or()
                .like(User::getEmail, keyword)
            );
        }
        
        // 状态筛选
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(User::getStatus, UserStatus.valueOf(status.toUpperCase()));
        }
        
        queryWrapper.orderByDesc(User::getCreatedAt);
        
        Page<User> result = userMapper.selectPage(userPage, queryWrapper);
        
        // 转换为响应对象
        Page<AdminUserResponse> responsePage = new Page<>();
        responsePage.setCurrent(result.getCurrent());
        responsePage.setSize(result.getSize());
        responsePage.setTotal(result.getTotal());
        responsePage.setPages(result.getPages());
        
        List<AdminUserResponse> responses = result.getRecords().stream()
            .map(this::convertToResponse)
            .collect(Collectors.toList());
        
        responsePage.setRecords(responses);
        
        return responsePage;
    }
    
    @Override
    public AdminUserResponse getAdminUserById(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        return convertToResponse(user);
    }
    
    @Override
    @Transactional
    public AdminUserResponse createAdminUser(AdminUserCreateRequest request) {
        // 获取当前登录用户的角色
        List<String> currentUserRoles = getCurrentUserRoles();
        log.info("当前用户角色: {}", currentUserRoles);
        
        // 验证角色权限：根据当前用户角色限制可创建的角色
        if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
            validateRolePermissions(currentUserRoles, request.getRoleIds());
        }
        
        // 检查用户名是否已存在
        LambdaQueryWrapper<User> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(User::getNickname, request.getNickname());
        if (userMapper.selectCount(checkWrapper) > 0) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查手机号是否已存在
        if (StringUtils.hasText(request.getPhone())) {
            LambdaQueryWrapper<User> phoneWrapper = new LambdaQueryWrapper<>();
            phoneWrapper.eq(User::getPhone, request.getPhone());
            if (userMapper.selectCount(phoneWrapper) > 0) {
                throw new RuntimeException("手机号已被使用");
            }
        }
        
        // 创建用户
        User user = new User();
        user.setOpenid(UUID.randomUUID().toString()); // 生成唯一openid
        user.setNickname(request.getNickname());
        user.setPasswordHash(passwordEncoder.encode(request.getPassword()));
        user.setPhone(request.getPhone());
        user.setEmail(request.getEmail());
        user.setAvatar(request.getAvatar());
        user.setRole(UserRole.ADMIN); // 默认设置为admin
        user.setStatus(UserStatus.valueOf(request.getStatus().toUpperCase()));
        user.setPoints(0);
        user.setLevel(1);
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());
        
        userMapper.insert(user);
        
        // 分配角色
        if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
            userRoleService.assignRoles(user.getId(), request.getRoleIds());
        }
        
        log.info("创建后台管理用户成功: userId={}, nickname={}, roles={}", user.getId(), user.getNickname(), request.getRoleIds());
        
        return convertToResponse(user);
    }
    
    @Override
    @Transactional
    public AdminUserResponse updateAdminUser(AdminUserUpdateRequest request) {
        User user = userMapper.selectById(request.getId());
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 更新基本信息
        if (StringUtils.hasText(request.getNickname())) {
            // 检查新用户名是否被占用
            LambdaQueryWrapper<User> checkWrapper = new LambdaQueryWrapper<>();
            checkWrapper.eq(User::getNickname, request.getNickname())
                .ne(User::getId, request.getId());
            if (userMapper.selectCount(checkWrapper) > 0) {
                throw new RuntimeException("用户名已被其他用户使用");
            }
            user.setNickname(request.getNickname());
        }
        
        if (StringUtils.hasText(request.getPassword())) {
            user.setPasswordHash(passwordEncoder.encode(request.getPassword()));
        }
        
        if (StringUtils.hasText(request.getPhone())) {
            user.setPhone(request.getPhone());
        }
        
        if (StringUtils.hasText(request.getEmail())) {
            user.setEmail(request.getEmail());
        }
        
        if (StringUtils.hasText(request.getAvatar())) {
            user.setAvatar(request.getAvatar());
        }
        
        if (StringUtils.hasText(request.getStatus())) {
            user.setStatus(UserStatus.valueOf(request.getStatus().toUpperCase()));
        }
        
        user.setUpdatedAt(LocalDateTime.now());
        userMapper.updateById(user);
        
        // 更新角色
        if (request.getRoleIds() != null) {
            userRoleService.assignRoles(user.getId(), request.getRoleIds());
        }
        
        log.info("更新后台管理用户成功: userId={}, nickname={}", user.getId(), user.getNickname());
        
        return convertToResponse(user);
    }
    
    @Override
    @Transactional
    public void deleteAdminUser(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 删除用户的角色关联
        userRoleMapper.deleteByUserId(id);
        
        // 删除用户
        userMapper.deleteById(id);
        
        log.info("删除后台管理用户成功: userId={}, nickname={}", id, user.getNickname());
    }
    
    @Override
    public void updateAdminUserStatus(Long id, String status) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(UserStatus.valueOf(status.toUpperCase()));
        user.setUpdatedAt(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("更新后台管理用户状态: userId={}, status={}", id, status);
    }
    
    @Override
    public void resetAdminUserPassword(Long id, String newPassword) {
        User user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        user.setPasswordHash(passwordEncoder.encode(newPassword));
        user.setUpdatedAt(LocalDateTime.now());
        userMapper.updateById(user);
        
        log.info("重置后台管理用户密码: userId={}", id);
    }
    
    @Override
    public Map<String, Object> getAdminUserStatistics() {
        Map<String, Object> stats = new HashMap<>();
        
        // 后台管理用户总数
        LambdaQueryWrapper<User> totalWrapper = new LambdaQueryWrapper<>();
        totalWrapper.in(User::getRole, UserRole.ADMIN, UserRole.VENUE_MANAGER);
        Long totalCount = userMapper.selectCount(totalWrapper);
        stats.put("totalCount", totalCount);
        
        // 活跃用户数
        LambdaQueryWrapper<User> activeWrapper = new LambdaQueryWrapper<>();
        activeWrapper.in(User::getRole, UserRole.ADMIN, UserRole.VENUE_MANAGER)
            .eq(User::getStatus, UserStatus.ACTIVE);
        Long activeCount = userMapper.selectCount(activeWrapper);
        stats.put("activeCount", activeCount);
        
        // 被禁用用户数
        LambdaQueryWrapper<User> bannedWrapper = new LambdaQueryWrapper<>();
        bannedWrapper.in(User::getRole, UserRole.ADMIN, UserRole.VENUE_MANAGER)
            .eq(User::getStatus, UserStatus.BANNED);
        Long bannedCount = userMapper.selectCount(bannedWrapper);
        stats.put("bannedCount", bannedCount);
        
        // 管理员数量
        LambdaQueryWrapper<User> adminWrapper = new LambdaQueryWrapper<>();
        adminWrapper.eq(User::getRole, UserRole.ADMIN);
        Long adminCount = userMapper.selectCount(adminWrapper);
        stats.put("adminCount", adminCount);
        
        // 场地管理员数量
        LambdaQueryWrapper<User> venueManagerWrapper = new LambdaQueryWrapper<>();
        venueManagerWrapper.eq(User::getRole, UserRole.VENUE_MANAGER);
        Long venueManagerCount = userMapper.selectCount(venueManagerWrapper);
        stats.put("venueManagerCount", venueManagerCount);
        
        // 最近7天新增数量
        LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);
        LambdaQueryWrapper<User> recentWrapper = new LambdaQueryWrapper<>();
        recentWrapper.in(User::getRole, UserRole.ADMIN, UserRole.VENUE_MANAGER)
            .ge(User::getCreatedAt, sevenDaysAgo);
        Long recentCount = userMapper.selectCount(recentWrapper);
        stats.put("recentSevenDaysCount", recentCount);
        
        return stats;
    }
    
    /**
     * 转换User为AdminUserResponse
     */
    private AdminUserResponse convertToResponse(User user) {
        AdminUserResponse response = new AdminUserResponse();
        response.setId(user.getId());
        response.setNickname(user.getNickname());
        response.setPhone(user.getPhone());
        response.setEmail(user.getEmail());
        response.setAvatar(user.getAvatar());
        response.setStatus(user.getStatus().getValue());
        response.setCreatedAt(user.getCreatedAt());
        response.setLastLoginAt(user.getLastLoginAt());
        
        // 获取用户的角色
        List<Role> roles = roleService.getRolesByUserId(user.getId());
        response.setRoles(roles);
        response.setRoleCodes(roles.stream().map(Role::getCode).collect(Collectors.toList()));
        response.setRoleNames(roles.stream().map(Role::getName).collect(Collectors.toList()));
        
        return response;
    }
    
    /**
     * 获取当前登录用户的角色列表
     */
    private List<String> getCurrentUserRoles() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException("未登录");
        }
        
        try {
            // 从JWT token中获取用户ID
            String userIdStr = authentication.getName();
            Long userId = Long.parseLong(userIdStr);
            
            // 获取用户角色
            List<Role> roles = roleService.getRolesByUserId(userId);
            return roles.stream().map(Role::getCode).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取当前用户角色失败", e);
            throw new RuntimeException("获取用户角色失败");
        }
    }
    
    /**
     * 验证角色创建权限
     * 规则：
     * 1. SUPER_ADMIN可以创建任何角色
     * 2. ADMIN只能创建CLUB_MANAGER和VENUE_MANAGER
     * 3. 其他角色不能创建用户
     */
    private void validateRolePermissions(List<String> currentUserRoles, List<Long> targetRoleIds) {
        // 获取目标角色信息
        List<Role> targetRoles = roleMapper.selectBatchIds(targetRoleIds);
        List<String> targetRoleCodes = targetRoles.stream()
            .map(Role::getCode)
            .collect(Collectors.toList());
        
        log.info("验证角色权限 - 当前用户角色: {}, 目标角色: {}", currentUserRoles, targetRoleCodes);
        
        // SUPER_ADMIN可以创建任何角色
        if (currentUserRoles.contains("SUPER_ADMIN")) {
            return;
        }
        
        // ADMIN只能创建CLUB_MANAGER和VENUE_MANAGER
        if (currentUserRoles.contains("ADMIN")) {
            List<String> allowedRoles = new ArrayList<>();
            allowedRoles.add("CLUB_MANAGER");
            allowedRoles.add("VENUE_MANAGER");
            allowedRoles.add("ADMIN");
            
            for (String roleCode : targetRoleCodes) {
                if (!allowedRoles.contains(roleCode)) {
                    throw new RuntimeException("您没有权限创建" + getRoleName(roleCode) + "角色的用户");
                }
            }
            return;
        }
        
        // 其他角色不允许创建用户
        throw new RuntimeException("您没有权限创建用户");
    }
    
    /**
     * 根据角色代码获取角色名称
     */
    private String getRoleName(String roleCode) {
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Role::getCode, roleCode);
        Role role = roleMapper.selectOne(wrapper);
        return role != null ? role.getName() : roleCode;
    }
}
